home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / eiffel / smalleif.97 / se.t / SmallEiffel / lib_std / std_file_read.e < prev    next >
Encoding:
Text File  |  1996-05-02  |  7.3 KB  |  326 lines

  1. -- Part of SmallEiffel -- Read DISCLAIMER file -- Copyright (C) 
  2. -- Dominique COLNET and Suzanne COLLIN -- colnet@loria.fr
  3. --
  4. class STD_FILE_READ 
  5. --
  6. -- Basic input facilities to read a named file on the disc.
  7. --
  8. -- Note : most features are common with STD_INPUT so you can 
  9. --        test your program on the screen first and then, just 
  10. --        changing of instance (STD_INPUT/STD_FILE_READ), doing 
  11. --        the same on a file.
  12. --
  13.    
  14. inherit STD_FILE
  15.    
  16. creation {ANY}
  17.    connect_to, make
  18.    
  19. feature {ANY}
  20.    
  21.    connect_to(new_path: STRING) is
  22.       do
  23.      make;
  24.      input_stream := fopen(new_path,mode);
  25.      if input_stream /= Void then
  26.         path := new_path;
  27.      end;
  28.       end;
  29.    
  30.    disconnect is
  31.       local
  32.      err: INTEGER;
  33.       do
  34.      err := fclose(input_stream); 
  35.      path := Void;
  36.       end;
  37.    
  38.    make is
  39.       do
  40.      mode := "r";
  41.       end;
  42.    
  43. feature {ANY}   
  44.    
  45.    last_integer: INTEGER; 
  46.      -- Last integer read using `read_integer'.
  47.    
  48.    last_real: REAL; -- Last real read with `read_real'.
  49.    
  50.    last_double: DOUBLE; -- Last double read with `read_double'.
  51.    
  52.    last_character: CHARACTER is 
  53.      -- Last character read with `read_character'.
  54.       do 
  55.      Result := last_character_memory;
  56.       end;
  57.    
  58.    last_string: STRING is
  59.      -- Last STRING read with `read_line', `read_word' or `newline'.
  60.      --
  61.      -- NOTE: it is alway the same STRING.
  62.       once
  63.      !!Result.make(256);
  64.       end;
  65.    
  66.    read_line is
  67.      -- Read a complete line ended by '%N' or `end_of_input'. 
  68.      -- Make the result available in `last_string'.
  69.      -- Character '%N' is not added in `last_string'. 
  70.      --     
  71.      -- NOTE: the result is available in `last_string' without any 
  72.      --       memory allocation.
  73.       require
  74.      not end_of_input;
  75.       do
  76.      read_line_in(last_string);
  77.       end;
  78.          
  79.    read_line_in(str: STRING) is
  80.      -- Same jobs as `read_line' but storage is directly done in `str'.
  81.      --
  82.       require
  83.      not end_of_input;
  84.       do
  85.      from  
  86.         str.clear;
  87.         read_character;
  88.      until
  89.         end_of_input or else
  90.         last_character = '%N'
  91.      loop
  92.         str.extend(last_character);
  93.         read_character;
  94.      end;
  95.       end;
  96.          
  97.    read_word is
  98.      -- Read a word using `is_separator' of class CHARACTER. 
  99.      -- Result is available in `last_string' (no allocation 
  100.      -- of memory).
  101.      -- Heading separators are automatically skipped.
  102.      -- Trailing separators are not skipped (`last_character' is
  103.      -- left on the first one).  
  104.      -- If `end_of_input' is encountered, Result can be the 
  105.      -- empty string.
  106.       require
  107.      not end_of_input;
  108.       do
  109.      skip_separators;
  110.      from  
  111.         last_string.clear;
  112.      until
  113.         end_of_input or else
  114.         last_character.is_separator
  115.      loop
  116.         last_string.extend(last_character);
  117.         read_character;
  118.      end;
  119.       end;
  120.    
  121.    skip_separators is
  122.      -- Stop doing `read_character' as soon as `end_of_file' is reached
  123.      -- or as soon as `last_character' is not `is_separator'.
  124.      -- When first character is already not `is_separator' nothing 
  125.      -- is done. 
  126.       do
  127.      from  
  128.      until
  129.         end_of_input or else 
  130.         not last_character.is_separator
  131.      loop
  132.         read_character;
  133.      end;
  134.       end;
  135.    
  136.    read_word_using(separators: STRING) is
  137.       -- Same jobs as `read_word' using `separators'.
  138.       do
  139.      not_yet_implemented;
  140.       end;
  141.          
  142.    read_integer is
  143.      -- Read an integer according to the Eiffel syntax.
  144.      -- Make result available in `last_integer'.
  145.      -- Heading separators (`is_separator' of CHARACTER)  
  146.      -- are automatically skipped.
  147.      -- Trailing sseparators are not skipped (`last_character'
  148.      -- is after the last digit of the number).
  149.       local
  150.      state: INTEGER;
  151.      sign: BOOLEAN;
  152.      -- state = 0 : waiting sign or first digit.
  153.      -- state = 1 : sign read, waiting first digit.
  154.      -- state = 2 : in the number.
  155.      -- state = 3 : end state.
  156.      -- state = 4 : error state.
  157.       do
  158.      from
  159.      until
  160.         state > 2
  161.      loop
  162.         read_character;
  163.         inspect 
  164.            state
  165.         when 0 then
  166.            if last_character.is_separator then
  167.            elseif last_character.is_digit then
  168.           last_integer := last_character.value;
  169.           state := 2;
  170.            elseif last_character = '-' then
  171.           sign := true;
  172.           state := 1;
  173.            elseif last_character = '+' then
  174.           state := 1;
  175.            else
  176.           state := 4;
  177.            end;
  178.         when 1 then
  179.            if last_character.is_separator then
  180.            elseif last_character.is_digit then
  181.           last_integer := last_character.value;
  182.           state := 2;
  183.            else
  184.           state := 4;
  185.            end;
  186.         else -- 2
  187.            if last_character.is_digit then
  188.           last_integer := (last_integer * 10) + last_character.value;
  189.            else
  190.           state := 3;
  191.            end;
  192.         end;
  193.      end;
  194.      if state = 4 then
  195.         std_error.put_string("Error in STD_FILE/read_integer.");
  196.      elseif sign then
  197.         last_integer := - last_integer;
  198.      end;
  199.       end;
  200.    
  201.    read_real is
  202.      -- Read a REAL and assign result to `last_real'.
  203.      -- The integral part is stored in `last_integer'.
  204.       local
  205.      i: INTEGER;
  206.       do
  207.      read_integer;
  208.      last_string.clear;
  209.      if last_character = '.' then
  210.         from  
  211.            read_character;
  212.            last_string.clear;
  213.         until
  214.            not last_character.is_digit
  215.         loop
  216.            last_string.extend(last_character);
  217.            read_character;
  218.         end;
  219.         from  
  220.            last_real := 0.0;
  221.            i := last_string.count;
  222.         until
  223.            i = 0
  224.         loop
  225.            last_real := (last_real + last_string.item(i).value) / 10;
  226.            i := i - 1;
  227.         end;
  228.         last_real := last_real + last_integer;
  229.      else
  230.         last_real := last_integer;
  231.      end;
  232.       end;
  233.    
  234.    read_double is
  235.      -- Read a DOUBLE according to the Eiffel syntax.
  236.      -- input and assign it to `last_real'.
  237.      -- The integral part is stored in `last_integer'.
  238.       local
  239.      i: INTEGER;
  240.       do
  241.      read_integer;
  242.      last_string.clear;
  243.      if last_character = '.' then
  244.         from  
  245.            read_character;
  246.            last_string.clear;
  247.         until
  248.            not last_character.is_digit
  249.         loop
  250.            last_string.extend(last_character);
  251.            read_character;
  252.         end;
  253.         from  
  254.            last_double := 0.0;
  255.            i := last_string.count;
  256.         until
  257.            i = 0
  258.         loop
  259.            last_double := (last_double + last_string.item(i).value) / 10;
  260.            i := i - 1;
  261.         end;
  262.         last_double := last_double + last_integer;
  263.      else
  264.         last_double := last_integer;
  265.      end;
  266.       end;
  267.    
  268.    unread_character is
  269.      -- Un read the last character read.
  270.       local
  271.      err: INTEGER;
  272.       do
  273.      err := ungetc(last_character,input_stream);
  274.       end;
  275.    
  276.    read_character is
  277.      -- Read a character and assign it to `last_character'.
  278.       require
  279.      not end_of_input;
  280.       do
  281.      last_character_memory := fgetc(input_stream);
  282.       end;
  283.    
  284.    newline is
  285.      -- Consume input until newline is found.
  286.      -- Corresponding STRING is stored in `last_string'.
  287.      -- Then consume newline character.
  288.       do
  289.      from  
  290.         last_string.clear;
  291.      until
  292.         end_of_input or else last_character = '%N'
  293.      loop
  294.         read_character;
  295.         last_string.extend(last_character);
  296.      end;
  297.      if not end_of_input then
  298.         read_character;
  299.      end;      
  300.       end;
  301.       
  302.    end_of_input : BOOLEAN is
  303.      -- Has end-of-input been reached ?
  304.       do
  305.      Result := feof(input_stream)
  306.       end;
  307.    
  308. feature {NONE}
  309.    
  310.    input_stream: POINTER;
  311.    
  312.    last_character_memory: CHARACTER;
  313.    
  314.    fgetc(stream_pointer : POINTER): CHARACTER is
  315.      -- Result is of type CHARACTER because a int is a char !
  316.       external "CSE"
  317.       alias "fgetc"
  318.       end;
  319.  
  320.    
  321.    feof(stream_ptr: POINTER): BOOLEAN is
  322.       external "CSE"
  323.       end;
  324.  
  325. end -- STD_FILE_READ
  326.